// *********************************************************
//      Copyright (c) Kosta Gaitanis
//      All rights reserved
//
//      k.gaitanis@gmail.com
//
// *********************************************************

#ifndef PLANET_H
#define PLANET_H

#include "Item.h"

/**
 * @brief The Planet class represents a planet and its satellites.
 * @author Kosta Gaitanis
 */
class Planet : public Item
{
public:
    enum Planets {
        Sun,
        Mercury,
        Venus,
        Earth,
        Mars,
        Jupiter,
        Saturn,
        Neptune,
        Uranus,
        Pluto,
        Moon,
        Io,
        Europa,
        Ganimede,
        Callisto
    };

    /**
     * @brief Constructs a new planet from a predefined set of available planets.
     * @param planet The planet to be constructed
     */
    Planet(Planets planet);

    /**
     * Destructor.
     */
    ~Planet();

    /**
     * @brief sets the planet Radius
     * @param radius (kilometers)
     */
    void setRadius(double radius);

    /**
     * @brief sets the planet Axial Tilt
     * @param axisDeviation (degrees)
     */
    void setAxialTilt(double axisDeviation);

    /**
     * @brief sets the distance from the parent planet.
     * @param distance (Astronomical Units = distance sun-earth)
     */
    void setDistanceFromCenter(double distance);

    /**
     * @brief sets the planet's Self Rotation Period
     * @param period (hours)
     */
    void setSelfRotationPeriod(double period);

    /**
     * @brief sets the planet's Rotation Period (around its sun)
     * @param period (years)
     */
    void setRotationPeriod(double period);

    /**
     * @brief sets the planet's Orbit Inclination
     * @param inclination (degrees)
     */
    void setOrbitInclination(double inclination);

    double getRadius() const;
    double getAxialTilt() const;
    double getDistanceFromCenter() const;
    double getSelfRotationPeriod() const;
    double getRotationPeriod() const;
    double getOrbitInclation() const;

    /**
     * @brief adds a satelite to this planet.
     * @param satelite The satelite to be added.
     */
    void addSatelite(Planet* satelite);

    /**
     * @brief Reimplements the Item::setTexture() to apply the texture to the planet
     *        child item instead of this item.
     * @param texture
     */
    virtual void setTexture(const Texture *texture);

protected:
    /**
     * @brief Called every time the current frame has changed. Adapts this
     * planets position and also sets the parentPosition of all the satellites.
     * @param frame The current frame.
     */
    virtual void onFrameChanged(double t);

private:
    double m_radius;
    double m_axialTilt;
    double m_distanceFromCenter;
    double m_selfRotationPeriod;
    double m_rotationPeriod;
    double m_orbitInclination;
};

#endif // PLANET_H
